package tsb.dtd;

import java.util.Stack;
import tsb.util.Balance;
import tsb.util.StrOp;

/**
 *
 * algunos metodos comunes para la validacion sintactica de un dtd
 */
public abstract class DTDTool {

    public static int getCantidadSalidasPar(final String str, final char c) {
        int n = -1;
        boolean esBalanceada = Balance.esbalanceada(str, '(', ')');
        if (esBalanceada) {
            n = 0;
        }
        char[] array = str.toCharArray();
        Stack<Character> stk = new Stack<Character>();

        for (int i = 0; esBalanceada && i < array.length; i++) {
            char d = array[i];
            if (d == '(') {
                stk.push(d);
            }
            if (stk.isEmpty() == false && d == ')') {
                if (stk.peek() == '(') {
                    stk.pop();
                }
                else {
                    stk.push(d);
                }
            }
            if (stk.isEmpty() && d == c) {
                n++;
            }
        }
        return n;
    }

    public static String extractList(final String str) {
        String resultado = null;
        String sinIniFin = StrOp.borrarInicioFin(str, "<!ELEMENT", ">");

        if (esBalanceadaYUnica(sinIniFin) == true) {
            int cierra = -1;
            int abre = -1;

            for (int i = 0; i < sinIniFin.length(); i++) {
                char ch = sinIniFin.charAt(i);
                if (ch == '(' && abre == -1) {
                    abre = i;
                }
                if (ch == ')') {
                    cierra = i;
                }
            }

            try {
                if (sinIniFin.charAt(cierra + 1) == '*' || sinIniFin.charAt(cierra + 1) == '?' || sinIniFin.charAt(cierra + 1) == '+') {
                    cierra += 2;
                } else {
                    cierra++;
                }
            } catch (IndexOutOfBoundsException ex) {
                cierra++;
            }
            resultado = sinIniFin.substring(abre, cierra);
        }
        return resultado;
    }

    private static boolean esBalanceadaYUnica(String str) {
        boolean resultado = true;
        Stack<String> stk = new Stack<String>();
        int root = 0;

        for (int i = 0; i < str.length(); i++) {
            String aux = String.valueOf(str.charAt(i));
            if (aux.equals("(") == true) {
                stk.push(aux);
            }
            else if (aux.equals(")") == true) {
                if (stk.isEmpty() == false &&stk.peek().equals("(") == true) {
                    stk.pop();
                    if (stk.isEmpty()) {
                        root++;
                    }
                }
                else {
                    stk.push(aux);
                }
            }
        }
        resultado = stk.isEmpty() && (root == 1);
        return resultado;
    }
}
